/* 
* sepsampler.h - This file is a part of the sep-library 
*
* Copyright (C) 2008 Jesper Schmidt Hansen 
* 
* License: GPL - see COPYING for copying conditions.
* There is ABSOLUTELY NO WARRANTY, not even for MERCHANTIBILITY or
* FITNESS FOR A PARTICULAR PURPOSE.
*
* Contact: schmidt@zigzak.net
*/


#ifndef __SEPSAMPLER_H__
#define __SEPSAMPLER_H__


#include "sep.h"
#include "complex.h"

/*********************************
 *
 * The different samplers
 *
 ************************************/

// sacf (atomic stress acf - contributions from dihedrals and angle not included!!)
typedef struct {
  unsigned i, lvec, nsample, isample;
  double dt, dtsample;

  double *sacf;  
  double **stress;
  
} sepsacf;


// msacf (molecular stress acf)
typedef struct {
  unsigned i, lvec, nsample, isample;
  double dt, dtsample;

  double **sacf;  
  double **sstress;
  double **astress;
  
} sepmsacf;


// dflux (molecular dipole flux tensor acf)
typedef struct {
  unsigned i, lvec, nsample, isample;
  double dt, dtsample;

  double **dflux;  
  double **acf;  
  
} sepdfluxacf;


// mcacf (couple-stress acf - always molecular)
typedef struct {
  unsigned i, lvec, nsample, isample;
  double dt, dtsample;

  double **cacf;  
  double **scouple;
  double **acouple;
  
} sepmcacf;


// vacf (atomic vel. acf)
typedef struct {
  unsigned i, lvec, nsample, isample;
  double dt, dtsample;

  double *vacf;  
  double **vels;

} sepvacf;

// mvacf (single molecular velocity acf)
typedef struct {
  unsigned i, lvec, nsample, isample;
  double dt, dtsample;

  double *vacf;  
  double **vels;

} sepmvacf;

// mavacf (single molecular angular velocity acf)
typedef struct {
  unsigned i, lvec, nsample, isample;
  double dt, dtsample;

  double *avacf;  
  double **avels;

} sepmavacf;

// gh (atomic generalized hydrodynamics sampler)
typedef struct {
  unsigned i, lvec, nsample, isample, nwave;
  double dt, dtsample, *k;

  complex double **fk_tv, **fkm_tv, **c_tv;
  complex double **fk_lv, **fkm_lv, **c_lv;
  complex double **fk_scatt, **fkm_scatt, **c_scatt;
  complex double **fk_cdens, **fkm_cdens, **c_cdens;

} sepgh;

// mgh (molecular generalized hydrodynamics)
typedef struct {
  unsigned i, lvec, nsample, isample, nwave;
  double dt, dtsample, *k;

  complex double **fk_tv, **fkm_tv, **c_tv;
  complex double **fk_lv, **fkm_lv, **c_lv;
  complex double **fk_scatt, **fkm_scatt, **c_scatt;
  complex double **fk_tav, **fkm_tav, **c_tav;
  complex double **fk_lav, **fkm_lav, **c_lav;
  complex double **fk_vav, **fkm_vav, **c_vav;
  complex double **fk_cdens, **fkm_cdens, **c_cdens;
  complex double **fk_tec, **fkm_tec, **c_tec;
  complex double **fk_lec, **fkm_lec, **c_lec;

  complex double  **c_tcav, **c_lcav;
  complex double  **c_cdensav;

} sepmgh;


// hprof (atomic flow hydrodynamic profiler - dens, velocity, temperature)
typedef struct {
  unsigned  lvec, nsample, isample;
  char type;
  double dir, dirvel;
  
  double *svel, *momc, *dens, *temp;

} sepprofs;

// hprof (molecular version)
typedef struct {
  unsigned  lvec, nsample, isample;
  char type;
  int dir, dirvel, diramom;
  
  double **amom, *momc, *dens, *temp, *numb;
  double ***inertia; 

} sepmprofs;



/***************************
 *
 *   Main structure 
 *
 ***************************/ 

typedef struct {

  sepmol *molptr;

  int flag_sacf; sepsacf *sacf;
  int flag_vacf; sepvacf *vacf;
  int flag_msacf; sepmsacf *msacf;
  int flag_mcacf; sepmcacf *mcacf;
  int flag_gh; sepgh *gh;
  int flag_mgh; sepmgh *mgh;
  int flag_profs; sepprofs *profs;
  int flag_mprofs; sepmprofs *mprofs;
  int flag_mvacf; sepmvacf *mvacf;
  int flag_mavacf; sepmavacf *mavacf;
  int flag_dfluxacf; sepdfluxacf *dfluxacf;

} sepsampler;



// Main structure prototypes
void sep_add_sampler(sepsampler *sptr, const char *sampler, 
		     sepsys sys, int lvec, ...);
void sep_close_sampler(sepsampler *ptr);
void sep_sample(seppart *pptr, sepsampler *sptr, sepret *ret, sepsys sys, 
		unsigned n);
void sep_add_mol_sampler(sepsampler *sptr, sepmol *mols);
sepsampler sep_init_sampler(void);


// sacf (atomic stress acf)
sepsacf *sep_sacf_init(int lvec, double tsample, double dt);
void sep_sacf_sample(sepsacf *sptr, sepret *ret, sepsys sys);
void sep_sacf_close(sepsacf *ptr);


// msacf (molecular stress acf)
sepmsacf *sep_msacf_init(int lvec, double tsample, double dt);
void sep_msacf_sample(sepmsacf *sptr, sepatom *atoms, sepmol *mols, 
		      sepret *ret, sepsys sys);
void sep_msacf_close(sepmsacf *ptr);

// vacf (atomic vel. acf)
sepvacf *sep_vacf_init(int lvec, double tsample, sepsys sys);
void sep_vacf_sample(seppart *ptr, sepvacf *vptr, sepsys sys);
void sep_vacf_close(sepvacf *ptr);

// mvacf (single molecular velocity acf)
sepmvacf *sep_mvacf_init(int lvec, double tsample, sepsys sys);
void sep_mvacf_sample(seppart *ptr, sepmvacf *vptr, sepmol *mols, sepsys sys);
void sep_mvacf_close(sepmvacf *ptr);

// gh (atomic generalized hydrodynamics)
sepgh *sep_gh_init(int lvec, double tsample, double dt, int nwave, 
		   double Ly);
void sep_gh_close(sepgh *ptr);
void sep_gh_sampler(sepatom *ptr, sepgh *gh, sepsys sys);

// mgh (molecular generalized hydrodynamics)
sepmgh *sep_mgh_init(int lvec, double tsample, double dt, int nwave, 
		     double Ly);
void sep_mgh_close(sepmgh *ptr);
void sep_mgh_sampler(sepatom *ptr, sepmol *mols, sepmgh *mgh, sepsys sys);

// hprof (atomic flow hydrodynamic profiler - dens, velocity, temperature)
sepprofs *sep_profs_init(char type, int lvec, int isample);
void sep_profs_close(sepprofs *ptr);
void sep_profs_sampler(seppart *pptr, sepprofs *ptr, sepsys sys);

// hprof (molecular version)
sepmprofs *sep_mprofs_init(char type, int lvec, int isample, int dir, int dirvel, 
			   int diramom);
void sep_mprofs_close(sepmprofs *ptr);
void sep_mprofs_sampler(seppart *pptr, sepmol *mols, sepmprofs *ptr, sepsys sys);

// mcacf (couple-stress acf - always molecular)
sepmcacf *sep_mcacf_init(int lvec, double tsample, double dt);
void sep_mcacf_sample(sepmcacf *sptr, sepatom *atoms, sepmol *mols, 
		      sepret *ret, sepsys sys);
void sep_mcacf_close(sepmcacf *ptr);

// mavacf (single molecular angular velocity acf)
sepmavacf *sep_mavacf_init(int lvec, double tsample, sepsys sys);
void sep_mavacf_sample(seppart *ptr, sepmavacf *vptr, sepmol *mols, sepsys sys);
void sep_mavacf_close(sepmavacf *ptr);


// Dipole flux 
sepdfluxacf *sep_dflux_init(int lvec, double tsample, double dt);
void sep_dflux_sample(sepatom *atoms, sepdfluxacf *sptr, sepmol *mols, sepsys sys);
void sep_dflux_close(sepdfluxacf *ptr);

#endif

